/**
##############################################################################

DOCOMO Innovations, Inc.

Copyright © 2011 DOCOMO Innovations, Inc. All rights reserved.

 

Date of Preparation: 08/01/2011

Contact: kozat@docomoinnovations.com

 

All intellectual property rights related to this software are vested in DOCOMO Innovations.

DOCOMO Innovations is under no obligation to maintain or support the software.

Neither DOCOMO Innovations nor its employees are responsible for any damage or loss resulting from the use of the software.

##############################################################################
 */

package umich.infinity.facebookconn;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.ByteBuffer;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import umich.infinity.proxy.Para;
import umich.infinity.proxy.SharedData;
import umich.infinity.proxy.Util;

public class FacebookUploadScheduler implements Runnable {
	SharedData sharedData;
	
	ThreadPoolExecutor uploadThreadPool;
	
	public FacebookUploadScheduler(SharedData sharedData) {
		this.sharedData = sharedData;
		
		uploadThreadPool = new ThreadPoolExecutor(Para.UploadThreadPoolSize, 
				Para.UploadThreadPoolMaxSize, Para.UploadThreadPoolKeepAliveTime,
				Para.ThreadPoolTimeUnit, new LinkedBlockingQueue<Runnable>());
	}
	
	class UploadTask implements Runnable {
		FacebookUploadReq req;
		public UploadTask(FacebookUploadReq req) {
			this.req = req;
		}
		
		@Override
		public void run() {
			FacebookUser fbUser = sharedData.fbUsers.get(req.uid);

			System.out.println("UploadTask for " + req.localPath);
			
			String aid=null; 

			try {
				String meReq = fbUser.facebook.request("me/albums");

				JSONObject meJson = FacebookUtil.parseJson(meReq);
				JSONArray albums = meJson.getJSONArray("data");

				aid = "";
				for (int i=0;i<albums.length();i++) {
					JSONObject album = albums.getJSONObject(i);
					if (album.has("name") && album.getString("name").compareTo(Para.FacebookAlbumName)==0) {
						aid = album.getString("id");
					}							
				}
			} catch (MalformedURLException e2) {
				e2.printStackTrace();
			} catch (IOException e2) {
				e2.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (FacebookError e) {
				e.printStackTrace();
			}

			if (aid.compareTo("") == 0) {
				Bundle params = new Bundle();

				params.putString("name", Para.FacebookAlbumName);
				String response = null;
				try {
					response = fbUser.facebook.request(fbUser.uid+"/albums", params, "POST");
				} catch (FileNotFoundException e1) {
					e1.printStackTrace();
				} catch (MalformedURLException e1) {
					e1.printStackTrace();
				} catch (IOException e1) {
					e1.printStackTrace();
				}

				if (response != null) {
					JSONObject json;
					try {
						json = FacebookUtil.parseJson(response);

						aid = json.getString("id");
					} catch (JSONException e) {
						e.printStackTrace();
					} catch (FacebookError e) {
						e.printStackTrace();
					}
				}
			}

			if (aid!= null && aid.length() > 0) {
				Bundle params = new Bundle();

				File pf = new File(req.localPath);
				FileInputStream fis;
				try {
					fis = new FileInputStream(pf);
					BufferedInputStream bis = new BufferedInputStream(fis);

					ByteBuffer buf = FacebookUtil.readBin(bis);
					bis.close();
				
					params.putByteArray("source", buf.array());
					
					String response = fbUser.facebook.request(aid + "/photos", params, "POST");
					
					JSONObject json = FacebookUtil.parseJson(response);
					final String src = json.getString("id");
					
					System.out.println("Successful upload with ID " + src);
					
					//TODO: per-user update check
					sharedData.wakeupUpdateScheduler();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (FacebookError e) {
					e.printStackTrace();
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		}
	}
		
	@Override
	public void run() {
		while (true) {
			if (sharedData.uploadQueue.size() > 0) {
				FacebookUploadReq req = null;
				synchronized (sharedData.uploadQueue) {
					req = sharedData.uploadQueue.removeFirst();
				}

				if (req != null) {
					UploadTask ut = new UploadTask(req);
					uploadThreadPool.submit(ut);
				}	
			} else {
				synchronized (this) {
					try {
						this.wait(0);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

}
